#ifdef WIN32
#define SPDLOG_WCHAR_FILENAMES
#endif

#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/async.h"

#include <iostream>
#include <QDebug>

#include "TLog.h"

std::unordered_map<std::string,TLog*> TLog::s_logs;

TLog *TLog::getLog(const std::string &id)
{
    auto it = s_logs.find(id);
    if (it == s_logs.end()) {
        throw id + "not register";
    }
    return it->second;
}

void TLog::addLog(const std::string &id,const std::string &pathAndFile,int log_level)
{
    spdlog::set_level(static_cast<spdlog::level::level_enum>(log_level));

    spdlog::flush_every(std::chrono::seconds(3));

    try {
        TLog* ptr = new TLog(id, pathAndFile,log_level);
        s_logs[id] = ptr;
    } catch (const spdlog::spdlog_ex &ex) {
        std::cout << ex.what();
    }
}

void TLog::flushLog(const std::string &id)
{
    auto it = s_logs.find(id);
    if (it == s_logs.end()) {
        throw id + "not register";
    }
    it->second->flush();
}

void TLog::freeLog()
{
    for (auto log : s_logs) {
        delete log.second;
    }
    spdlog::drop_all();
}

void TLog::flush()
{
    m_logger->flush();
}

void TLog::endLog()
{
    try {
        m_logger->flush();
    } catch(std::exception e) {
        std::cout << e.what();
    }
}

TLog::TLog(const std::string &id,const std::string &pathAndFile, int log_level)
{
    try {
#ifdef WIN32
        QString s(pathAndFile.c_str());
        m_logger = spdlog::basic_logger_mt<spdlog::async_factory >(id, s.toStdWString());
#else
        m_logger = spdlog::basic_logger_mt<spdlog::async_factory >(id, pathAndFile);
#endif
        m_logger->flush_on(spdlog::level::err);
        m_logger->set_pattern("[%C-%m-%d %H:%M:%S:%e] [T %t] [%L] %v");
    } catch (const spdlog::spdlog_ex &ex) {
        std::cout << ex.what();
    }
}

TLog::~TLog()
{
    endLog();
}

void TLog::setLevel(int level)
{
    spdlog::set_level(static_cast<spdlog::level::level_enum>(level));
}
